﻿using Chemistry.Models;
using Chemistry.Tools;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chemistry.ViewModels
{
    public class ConfigScoreViewModel:VmBase
    {
        #region  属性
        private int _min_index;
        private int _max_index;
        private int _min_index2;
        private int _max_index2;

        private ObservableCollection<PropertyNodeItem> nodes;
        public ObservableCollection<PropertyNodeItem> NodeList
        {
            get { return nodes; }
            set { nodes = value; RaisePropertyChanged("NodeList"); }
        }

        public Workflow SelectedWorkFlow { get; set; }

        private ObservableCollection<Detail> _details;

        public ObservableCollection<Detail> Details
        {
            get { return _details; }
            set { _details = value; RaisePropertyChanged("Details"); }
        }

        private ObservableCollection<Abnormal> _abnormals;

        public ObservableCollection<Abnormal> Abnormals
        {
            get { return _abnormals; }
            set { _abnormals = value; RaisePropertyChanged("Abnormals"); }
        }

        private Abnormal _selectedAbnormal;

        public Abnormal SelectedAbnormal
        {
            get { return _selectedAbnormal; }
            set
            {
                _selectedAbnormal = value;
                RaisePropertyChanged("SelectedAbnormal");
            }
        }

        private Detail _detail;

        public Detail SelectedDetail
        {
            get { return _detail; }
            set
            {
                _detail = value;
                RaisePropertyChanged("SelectedDetail");
            }
        }
        #endregion


        #region 按钮 Enabled
        private bool _isupEnabled;

        public bool IsUpEnabled
        {
            get { return _isupEnabled; }
            set { _isupEnabled = value; RaisePropertyChanged("IsUpEnabled"); }
        }

        private bool _isdownEnabled;

        public bool IsDownEnabled
        {
            get { return _isdownEnabled; }
            set { _isdownEnabled = value; RaisePropertyChanged("IsDownEnabled"); }
        }

        private bool _isupEnabled2;

        public bool IsUpEnabled2
        {
            get { return _isupEnabled2; }
            set { _isupEnabled2 = value; RaisePropertyChanged("IsUpEnabled2"); }
        }

        private bool _isdownEnabled2;

        public bool IsDownEnabled2
        {
            get { return _isdownEnabled2; }
            set { _isdownEnabled2 = value; RaisePropertyChanged("IsDownEnabled2"); }
        }

        private bool _isDeleteDetailEnbaled;

        public bool IsDeleteDetailEnabled
        {
            get { return _isDeleteDetailEnbaled; }
            set { _isDeleteDetailEnbaled = value; RaisePropertyChanged("IsDeleteDetailEnabled"); }
        }

        private bool _isDeleteAbnormalEnabled;

        public bool IsDeleteAbnormalEnabled
        {
            get { return _isDeleteAbnormalEnabled; }
            set { _isDeleteAbnormalEnabled = value; RaisePropertyChanged("IsDeleteAbnormalEnabled"); }
        }

        #endregion

        public RelayCommand UpCommand { get; set; }
        public RelayCommand DownCommand { get; set; }
        public RelayCommand DeleteDetailCommand { get; set; }

        public RelayCommand UpCommand2 { get; set; }
        public RelayCommand DownCommand2 { get; set; }
        public RelayCommand DeleteAbnormal { get; set; }
        public RelayCommand CommitCommand2 { get; set; }

        public ConfigScoreViewModel()
        {
            InitFlows();
            UpCommand = new RelayCommand(UpExec, () => SelectedDetail != null && SelectedDetail.Index > _min_index);
            DownCommand = new RelayCommand(DownExec, () => SelectedDetail != null && SelectedDetail.Index < _max_index);
            DeleteDetailCommand = new RelayCommand(DeleteDetailExec, ()=> SelectedDetail!=null); 
            CommitCommand = new RelayCommand(CommitExec,()=> this.Details!=null&& this.Details.Count>0);

            UpCommand2 = new RelayCommand(UpExec2,()=>SelectedAbnormal!=null && SelectedAbnormal.Index>_min_index2);
            DownCommand2 = new RelayCommand(DownExec2, () => SelectedAbnormal != null && SelectedAbnormal.Index < _max_index2);
            DeleteAbnormal = new RelayCommand(DeleteAbnormalExec,()=>SelectedAbnormal!=null);
            CommitCommand2 = new RelayCommand(CommitExec2,()=>Abnormals!=null&& Abnormals.Count>0);

            InitMessage();
        }

        private void InitMessage()
        {
            Register<PropertyNodeItem>(this, MessageToken.SelectFlow,async (i) => {
                SelectedWorkFlow = i.Tag as Workflow;
                await FreshDetail(SelectedWorkFlow.Id);
                await FreshAbnormal(SelectedWorkFlow.Id);
            });
        }

        #region 异常  命令方法
        private async void CommitExec2()
        {
            if (this.Abnormals == null || this.Abnormals.Count == 0) return;

            int index = 1;
            foreach (var item in Abnormals)
            {
                if (item.Id == 0)
                {
                    index++;
                    item.Index = index;
                    item.WorkFlowId = SelectedWorkFlow.Id;
                }
                else
                {
                    index = item.Index;
                }
            }
            string request_url = string.Format("{0}/ModifyAbnormal", workflow_url);
            var result = await HttpBaseChemistry.PostAsJsonAsync<ChemistryApiReuslt>(request_url, this.Abnormals.ToList());
            if (result.status == 1)
            {
                ShowMessage("已添加相同的步骤，请重新检查步骤是否重复");
            }
            else if (result.status == -3)
            {
                ShowMessage("服务器内部错误，请联系管理员");
            }
            int flowid = SelectedWorkFlow.Id;
            await FreshAbnormal(flowid);
        }


        private async void DeleteAbnormalExec()
        {
            if (SelectedAbnormal.Id == 0)
            {
                Abnormals.Remove(SelectedAbnormal);
            }
            else
            {
                string request_url = string.Format("{0}/DeleteAbnormal?abnormalid={1}", workflow_url, SelectedAbnormal.Id);
                var message = await HttpBaseChemistry.GetAsync<string>(request_url);

                if (!string.IsNullOrEmpty(message))
                    ShowMessage("错误" + message);
                else
                {
                    await FreshAbnormal(SelectedWorkFlow.Id);
                }
            }
        }

        private void DownExec2()
        {
            int nextIndex = SelectedAbnormal.Index + 1;
            var nextDetail = Abnormals.Where(i => i.Index == nextIndex).SingleOrDefault().Index--;
            SelectedAbnormal.Index++;
            var result = Abnormals.OrderBy(i => i.Index);
            Abnormals = new ObservableCollection<Abnormal>(result);
        }

        private void UpExec2()
        {
            int nextIndex = SelectedAbnormal.Index - 1;
            var nextDetail = Abnormals.Where(i => i.Index == nextIndex).SingleOrDefault().Index++;
            SelectedAbnormal.Index--;
            var result = Abnormals.OrderBy(i => i.Index);
            Abnormals = new ObservableCollection<Abnormal>(result);
        } 
        #endregion

        #region 步骤 命令方法
        private async void DeleteDetailExec()
        {
            if (SelectedDetail.Id == 0)
            {
                Details.Remove(SelectedDetail);
            }
            else
            {
                try
                {
                    string request_url = string.Format("{0}/DeleteDetail?detailid={1}", workflow_url, SelectedDetail.Id);
                    var message = await HttpBaseChemistry.GetAsync<ChemistryApiReuslt>(request_url);
                    
                }
                catch (Exception ex)
                {
                    AppendExecptionAsync(ex);
                    ShowMessage("错误：" + ex.Message);
                }
            }
        }

        private void DownExec()
        {
            int nextIndex = SelectedDetail.Index + 1;
            var nextDetail = Details.Where(i => i.Index == nextIndex).SingleOrDefault().Index--;
            SelectedDetail.Index++;
            var result = Details.OrderBy(i => i.Index);
            Details = new ObservableCollection<Detail>(result);
        }


        private void UpExec()
        {
            int prevIndex = SelectedDetail.Index - 1;
            Details.SingleOrDefault(i => i.Index == prevIndex).Index++;
            SelectedDetail.Index--;
            var result = Details.OrderBy(i => i.Index);
            Details = new ObservableCollection<Detail>(result);
        }
        private async void CommitExec()
        {
            int index = 1;
            foreach (var item in Details)
            {
                if (item.Id == 0)
                {
                    index++;
                    item.Index = index;
                    item.WorkFlowId = SelectedWorkFlow.Id;
                }
                else
                {
                    index = item.Index;
                }
            }
            string request_url = string.Format("{0}/ModifyDetail", workflow_url);
            try
            {
                var result = await HttpBaseChemistry.PostAsJsonAsync<ChemistryApiReuslt>(request_url, Details);
                if (result.status == 1)
                {
                    ShowMessage("已添加相同的步骤，请重新检查步骤是否重复");
                }
                else if (result.status == -3)
                {
                    ShowMessage("服务器内部错误，请联系管理员");
                }
                int flowid = SelectedWorkFlow.Id;
                await FreshDetail(flowid);
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
                ShowMessage(ex.Message);
            }
        }

       

        #endregion

        #region Async 方法
        async Task FreshAbnormal(int flowid)
        {
            var list =   await GetAbnormalByFlowId(flowid);
            if (list != null && list.Count > 0)
            {
                Abnormals = new ObservableCollection<Abnormal>(list);
                _min_index2 = Abnormals.Min(i => i.Index);
                _max_index2 = Abnormals.Max(i => i.Index);
            }
            else
            {
                Abnormals = new ObservableCollection<Abnormal>();
            }
        }

        private async Task FreshDetail(int flowid)
        {
            List<Detail> details = await GetDetailByFlowId(flowid);
            Details = new ObservableCollection<Detail>(details);
            if (Details != null && Details.Count > 0)
            {
                _min_index = details.Min(i => i.Index);
                _max_index = details.Max(i => i.Index);
            }
        }

        private async Task<List<Detail>> GetDetailByFlowId(int flowid)
        {
            List<Detail> details = null;
            try
            {
                string request_url = string.Format("{0}/GetDetailsByFlowId?flowId={1}", workflow_url, flowid);
                var result = await HttpBaseChemistry.GetAsync<DetaiApiModel>(request_url);
                if (result!=null&& result.status == 0)
                    details = result.details;
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
            }
            return details;
        }

        private async void InitFlows()
        {
            string request_url = string.Format("{0}/GetWorkflow", workflow_url);
            var workflowapi_result = await HttpBaseChemistry.GetAsync<WorkflowApiModel>(request_url);
            if (workflowapi_result != null && workflowapi_result.status == 0)
            {
                NodeList = new ObservableCollection<PropertyNodeItem>();
                var flows = workflowapi_result.Workflows;
                foreach (var item in flows)
                {
                    PropertyNodeItem pitem = new PropertyNodeItem()
                    {
                        Name = item.Name,
                        Tag = item
                    };
                    NodeList.Add(pitem);
                }
            }
            
        }

        async Task<List<Abnormal>> GetAbnormalByFlowId(int flowId)
        {
            List<Abnormal> list =null;
            try
            {
                string request_url = string.Format("{0}/GetAbnormalsByFlowId?flowId={1}", workflow_url, flowId);
                var result = await HttpBaseChemistry.GetAsync<AbnormalApiModel>(request_url);
                if (result != null && result.status == 0)
                    list = result.abnormals;
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
            }
            return list;
        }
        #endregion


    }
}
